package com.smart.seckilldemo.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.smart.seckilldemo.commons.Parameters;
import com.smart.seckilldemo.commons.dto.GenerateSeckillOrder;
import com.smart.seckilldemo.commons.result.ResponseResult;
import com.smart.seckilldemo.commons.result.ResultCodeEnum;
import com.smart.seckilldemo.pojo.Good;
import com.smart.seckilldemo.pojo.SeckillGoods;
import com.smart.seckilldemo.rocketmq.producer.RocketMQProducer;
import com.smart.seckilldemo.service.*;
import com.smart.seckilldemo.utils.RandomLongUtil;
import com.smart.seckilldemo.utils.RedisJudgeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class SeckillServiceImpl implements SeckillService {


    @Resource
    SeckillGoodsService seckillGoodsService;
    @Resource
    RedisJudgeUtils redisJudgeUtils;
    @Resource
    SeckillOrderService seckillOrderService;
    @Resource
    InventorySeckillGoods inventorySeckillGoods;
    @Resource
    RocketMQProducer rocketMQProducer;
    @Resource
    GoodsService goodsService;


    @Override
    public ResponseResult Seckill(Long userId, Long goodId) {
        //获取秒杀商品信息 商品库存信息
        //秒杀商品信息
        String SeckillGoodKey= Parameters.SeckillGoodsDateCache+":"+goodId;
        //商品库存信息
        String GoodInventory=Parameters.SeckillGoodInventory+":"+goodId;
        SeckillGoods seckillGoods = (SeckillGoods) redisJudgeUtils.getRed(SeckillGoodKey);
        if(seckillGoods==null){
            //从数据库拿 存入缓存
            seckillGoods = seckillGoodsService.getSeckillGoods(goodId);
            redisJudgeUtils.setRed(SeckillGoodKey,seckillGoods);
            //存入库存信息
            redisJudgeUtils.setRed(GoodInventory,seckillGoods.getStockCount());
        }
        //判断时间
        if(seckillGoods.getStartDate().getTime()<new Date().getTime()){
            return ResponseResult.error(ResultCodeEnum.TIME_NO_ERROR);
        }
        //判断是否有库存
        if(seckillGoods.getStockCount()<1){
            return ResponseResult.error(ResultCodeEnum.PERMISSION_NO_STOCK);
        }
        //判断用户资格
        if(!seckillOrderService.getOrderThere(userId,goodId,1)){
            return ResponseResult.error(ResultCodeEnum.PERMISSION_NO_PRODUCT);
        }
        //锁内减库存
        if(!inventorySeckillGoods.InventorySeckillGoods(userId,goodId)){
            log.info("扣减库存失败 稍后重试");
            return ResponseResult.error(ResultCodeEnum.PERMISSION_NO_PRODUCT);
        }
        //库存统一
        int red = (int) redisJudgeUtils.getRed(GoodInventory);
        seckillGoods.setStockCount(red);
        redisJudgeUtils.setRed(SeckillGoodKey,seckillGoods);
        //生成订单编号
        Long orderId = RandomLongUtil.randomLong(12);
        log.info("生成订单号"+orderId);
        //创建订单生成工具类
        GenerateSeckillOrder msg = new GenerateSeckillOrder();
        msg.setUserId(userId);
        msg.setGoodsId(goodId);
        msg.setNumber(1);//购买一件
        msg.setOrderId(orderId);
        //更新界面缓存
        //  redisJudgeUtils.deleteRed(Parameters.SeckillGoodsDateCache+":"+goodId);
        log.info("锁定库存 发送消息生成订单");
        //发送消息 后台生成订单
        rocketMQProducer.onMessage(msg);
        //返回订单号
        return ResponseResult.success(orderId);
    }

    /**
     * 预热
     */
    @Override
    public void DataLoaderSeckill() {

        //获取预热秒杀商品数据
        List<Good> seckillGood = goodsService.findSeckillGood();
        seckillGood.forEach(s->{
            redisJudgeUtils.setRed(Parameters.SeckillGoodsDateCache+":"+s.getGoodId(),seckillGoodsService.getSeckillGoods(s.getGoodId()));
            redisJudgeUtils.setRed(Parameters.SeckillGoodInventory+":"+s.getGoodId(),seckillGoodsService.getSeckillGoods(s.getGoodId()).getStockCount());
        });
    }
}
